#include <iostream>
#include <sstream>
#include <string>
#include <memory>
#include <jsoncpp/json/json.h>
#include <algorithm>


// int main()
// {
//     Json::Value stu;
//     std::stringstream ss;

//     stu["姓名"] = "xiaoming";
//     stu["年龄"] = 18;
//     stu["成绩"].append(90);
//     stu["成绩"].append(95);
//     stu["成绩"].append(98);

//     // 序列化: json对象->json格式的字符串
//     Json::StreamWriterBuilder swb;
//     swb.settings_["emitUTF8"] = true;

//     // Json::StreamWriter* swptr = swb.newStreamWriter();
//     // std::unique_ptr<Json::StreamWriter> swPtr(swptr);
//     std::unique_ptr<Json::StreamWriter> swPtr(swb.newStreamWriter());

//     int ret = swPtr->write(stu, &ss);
//     if(ret != 0)
//     {
//         std::cout << "序列化失败!!!" << std::endl;
//         return -1;
//     }
//     else
//     {
//         std::cout << "序列化的结果为: " << std::endl;
//         std::cout << ss.str() << std::endl << std::endl;
//     }
    

//     // 反序列化: json格式的字符串 -> json对象
//     std::string jsonStr(ss.str());
//     Json::Value jsonValue;

//     Json::CharReaderBuilder crb;
//     std::unique_ptr<Json::CharReader> crPtr(crb.newCharReader());
//     ret = crPtr->parse(jsonStr.c_str(), jsonStr.c_str()+jsonStr.size(), &jsonValue, nullptr);
//     if(!ret)
//     {
//         std::cout << "反序列化失败" << std::endl;
//         return -1;
//     }
//     else
//     {
//         std::cout << "反序列化的结果: " << std::endl;
//         std::cout << "姓名: " << jsonValue["姓名"].asString() << std::endl;
//         std::cout << "年龄: " << jsonValue["年龄"].asString() << std::endl;
//         std::cout << "语文: " << jsonValue["成绩"][0].asFloat() << std::endl;
//         std::cout << "数学: " << jsonValue["成绩"][1].asFloat() << std::endl;
//         std::cout << "英语: " << jsonValue["成绩"][2].asFloat() << std::endl;
//     }

//     return 0;
// }


// 封装成接口

bool serialize(const Json::Value& jsonValue, std::string& jsonStr)
{
    Json::StreamWriterBuilder swb;
    std::unique_ptr<Json::StreamWriter> swPtr(swb.newStreamWriter());

    std::stringstream ss;
    if(swPtr->write(jsonValue, &ss) != 0)
    {
        std::cout << "序列化失败" << std::endl;
        return false;
    }
    else
    {
        std::cout << "序列化成功" << std::endl;
        jsonStr = ss.str();
    }

    return true;
}   



bool unserialize(const std::string& jsonStr, Json::Value& jsonValue)
{
    Json::CharReaderBuilder crb;
    std::string errorMsg;

    std::unique_ptr<Json::CharReader> crPtr(crb.newCharReader());
    
    bool ret = crPtr->parse(jsonStr.c_str(), jsonStr.c_str()+jsonStr.size(), &jsonValue, &errorMsg);
    
    if(ret == false)
    {
        std::cout << "反序列化失败" << std::endl;
        std::cout << "失败原因: " << errorMsg << std::endl;
        return false;
    }
    else
    {
        std::cout << "反序列化成功" << std::endl;
    }

    return true;
}


int main()
{
    const char *name = "小明";
    int age = 18; 
    const char *sex = "男";
    float score[3] = {88, 77.5, 66};

    Json::Value student;
    student["姓名"] = name;
    student["年龄"] = age;
    student["性别"] = sex;
    student["成绩"].append(score[0]);
    student["成绩"].append(score[1]);
    student["成绩"].append(score[2]);
    
    Json::Value fav;
    fav["书籍"] = "西游记";
    fav["运动"] = "打篮球";
    student["爱好"] = fav;

    // 序列化
    std::string body;
    serialize(student, body);

    std::cout << body << std::endl;

    // 反序列化
    std::string str = R"({"姓名":"小黑", "年龄": 19, "成绩":[32, 45, 56]})";
    Json::Value stu;
    bool ret = unserialize(str, stu);
    if (ret == false) 
        return -1;

    std::cout << "姓名: " <<  stu["姓名"].asString() << std::endl;
    std::cout << "年龄: " <<  stu["年龄"].asInt() << std::endl;

    int sz = stu["成绩"].size();
    for (int i = 0; i < sz; i++) {
        std::cout << "成绩: " <<  stu["成绩"][i].asFloat() << std::endl;
    }

    return 0;
}